home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
9675
/
9675.xpi
/
chrome
/
content
/
simpletimer-dragndrop.js
< prev
next >
Wrap
Text File
|
2009-11-20
|
11KB
|
249 lines
// Based on code taken from the IE Tab add-on, as well as the template at
// http://kb.mozillazine.org/Dev_:_Extensions_:_Example_Code_:_Adding_Drag_and_Drop_to_Statusbarpanel
// Fixed some bugs, and didn't like how IE Tab displayed hidden panels while dragging (changed).
// Also, some themes do not display the red vertical line while dragging, fiddled with CSS
// but no luck.
var SimpleStatObserver = {
init: function () {
// Any text you want but should have something to do with the extension name.
SimpleStatObserver.flavour = "SimpleTimerFla";
// id of the statusbarpanel to drag.
SimpleStatObserver.statusbarPanel = "simtim-statpanelTimer";
// id of statusbar.
SimpleStatObserver.statbar = "status-bar";
try {
SimpleStatObserver.prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService).
getBranch("extensions.simpletimer@grbradt.org.");
// Checks whether the preference has been changed from the default value (empty string)
// and inserts our panel before the element referenced in preference.
// Default position is last.
if ( SimpleStatObserver.prefs.prefHasUserValue("insertBefore") &&
SimpleStatObserver.prefs.getCharPref("insertBefore") !== "last" ) {
document.getElementById(SimpleStatObserver.statbar).
insertBefore(document.getElementById(SimpleStatObserver.statusbarPanel),
document.getElementById(SimpleStatObserver.prefs.getCharPref("insertBefore")));
}
else {
document.getElementById(SimpleStatObserver.statbar).
appendChild(document.getElementById(SimpleStatObserver.statusbarPanel));
}
}
catch(e) {
document.getElementById(SimpleStatObserver.statbar).
appendChild(document.getElementById(SimpleStatObserver.statusbarPanel));
}
// Starting with FF 3.6, dragdrop event replaced by drop event.
// Both events were available in FF 3.5 (first implementation of HTML5 dnd).
SimpleStatObserver.dropEvent = "drop";
try {
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo);
var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"].
getService(Components.interfaces.nsIVersionComparator);
if ( appInfo.name === "Firefox" ) {
if ( versionChecker.compare(appInfo.version, "3.6a1" ) < 0 ) {
SimpleStatObserver.dropEvent = "dragdrop";
}
}
}
catch(e) {
}
},
// The type of data being dragged is stored as a set of flavours.
// Often, a dragged object will be available in a number of flavours.
// That way, a drop target can accept the flavour it finds most suitable.
getSupportedFlavours: function () {
var flavours = new FlavourSet();
flavours.appendFlavour(SimpleStatObserver.flavour); // text/unicode
return flavours;
},
// Begin drag, set the transfer data and attach drag event listeners
// to each statusbar panel.
onDragStart: function (evt, transferData, action) {
var elme = evt.target;
// See if target element was child label or image, eg.
while ( elme != document.getElementById(SimpleStatObserver.statusbarPanel) ) {
elme = elme.parentNode;
}
// Data being transferred is our panel id, in text/unicode format
var txt = elme.getAttribute("id");
transferData.data = new TransferData();
transferData.data.addDataForFlavour(SimpleStatObserver.flavour, txt);
var statusPanel = document.getElementById(SimpleStatObserver.statusbarPanel);
var statusbar = document.getElementById(SimpleStatObserver.statbar);
var child = statusbar.firstChild;
var x = 0;
// Check if each panel has id, add listeners to each panel.
// Keep in mind that some children of statusbar may not be statusbarpanels,
// eg deck, popupset etc.
while ( child ) {
if ( child != statusPanel ) {
if ( !child.id ) {
// If you insert before a no-id, positioning is lost
// on browser restart. id doesn't persist.
var newId = "statusbarpanel-noID" + x;
while ( document.getElementById(newId) ) {
newId += "x" + x;
}
child.id = newId;
child.setAttribute("persist",
new String("id" + (child.persist ? " " + child.persist : "")));
x++;
}
child.addEventListener("dragenter", function(event) { nsDragAndDrop.dragEnter(event, SimpleStatObserver); }, false);
child.addEventListener("dragover", function(event) { nsDragAndDrop.dragOver(event, SimpleStatObserver); }, false);
child.addEventListener("dragexit", function(event) { nsDragAndDrop.dragExit(event, SimpleStatObserver); }, false);
child.addEventListener(SimpleStatObserver.dropEvent, function(event) { nsDragAndDrop.drop(event, SimpleStatObserver); }, false);
}
child = child.nextSibling;
}
window.addEventListener("dragend", function(event) { SimpleStatObserver.dragEnd(); }, true);
},
// Entering a panel.
onDragEnter: function (evt, flavour, session) {
var elm = evt.target;
while ( elm && elm.nodeName.toLowerCase() != "statusbarpanel" ) {
elm = elm.parentNode;
}
},
// Moving over a panel.
onDragOver: function (evt, flavour, session) {
var elm = evt.target;
while ( elm.nodeName.toLowerCase() != "statusbarpanel" &&
elm.parentNode.nodeName.toLowerCase() != "statusbar" ) {
elm = elm.parentNode;
}
// This will display a little vertical red line where the drop will occur.
// Calculate mid-point of panel we are moving over.
var midPointCoord = elm.boxObject.x + ( elm.boxObject.width / 2 );
if ( evt.clientX < midPointCoord ) {
elm.setAttribute("simtimstatdrag", "left");
}
else {
elm.setAttribute("simtimstatdrag", "right");
}
},
// Leaving a panel. Remove the vertical red line.
onDragExit: function (evt, session) {
var elm = evt.target;
while ( elm.nodeName.toLowerCase() != "statusbarpanel" &&
elm.parentNode.nodeName.toLowerCase() != "statusbar" ) {
elm = elm.parentNode;
}
elm.removeAttribute("simtimstatdrag");
},
// Dropped.
onDrop: function (evt, dropdata, session) {
if ( dropdata.data != "" ) {
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService).
getBranch("extensions.simpletimer@grbradt.org.");
var elm = evt.target;
// May have dropped on image or label.
while ( elm.parentNode.nodeName.toLowerCase() != "statusbar" ) {
elm = elm.parentNode;
}
// Calculate mid-point again.
var midPointCoord = elm.boxObject.x + ( elm.boxObject.width / 2 );
// elem is the dropped panel.
var elem = document.getElementById(dropdata.data);
var parent = elem.parentNode;
if ( evt.clientX > midPointCoord ) {
// Dropped on right side of mid-point.
elm = elm.nextSibling;
if ( elm == elem ) {
elm = elm.nextSibling;
}
}
// Don't insert before non-panel/deck statusbar children eg popupset.
while ( elm && ( ( elm.nodeName.toLowerCase() != "statusbarpanel" &&
elm.nodeName.toLowerCase() != "deck" ) ||
elm == elem ) ) {
elm = elm.nextSibling;
}
if ( elm ) {
try {
parent.insertBefore(elem, elm);
}
catch(e) {
}
elem.setAttribute("insertbefore", "" + elm.getAttribute("id"));
prefs.setCharPref("insertBefore", elm.getAttribute("id") + "");
}
else {
parent.appendChild(elem);
elem.setAttribute("insertbefore", "last");
prefs.setCharPref("insertBefore", "last");
}
}
},
// Clean up.
dragEnd: function () {
var statusbar = document.getElementById(SimpleStatObserver.statbar);
var statusbarPanel = document.getElementById(SimpleStatObserver.statusbarPanel);
// Remove the event handlers
var child = statusbar.firstChild;
while (child) {
if ( child != statusbarPanel ) {
child.removeAttribute("simtimstatdrag");
child.removeEventListener("dragenter", function(event) { nsDragAndDrop.dragEnter(event, SimpleStatObserver); }, false);
child.removeEventListener("dragover", function(event) { nsDragAndDrop.dragOver(event, SimpleStatObserver); }, false);
child.removeEventListener("dragexit", function(event) { nsDragAndDrop.dragExit(event, SimpleStatObserver); }, false);
child.removeEventListener(SimpleStatObserver.dropEvent, function(event) { nsDragAndDrop.drop(event, SimpleStatObserver); }, false);
}
child = child.nextSibling;
}
window.removeEventListener("dragend", function(event) { nsDragAndDrop.dragExit(event, SimpleStatObserver); }, true);
},
goodbye: function() {
window.removeEventListener('load', SimpleStatObserver.init, false);
window.removeEventListener('unload', SimpleStatObserver.goodbye, false);
},
debug: function (aMsg) {
setTimeout(function() { throw new Error("[debug] " + aMsg); }, 0);
}
};
window.addEventListener('load', SimpleStatObserver.init, false);
window.addEventListener('unload', SimpleStatObserver.goodbye, false);